package com.atstudent.gmall.cart.biz.impl;
import java.math.BigDecimal;
import java.util.Date;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import com.alibaba.fastjson.JSON;
import com.atstudent.gmall.cart.biz.CartBizService;
import com.atstudent.gmall.cart.entity.CartItem;
import com.atstudent.gmall.cart.vo.AddCartSuccessVo;
import com.atstudent.gmall.common.constant.GmallConstant;
import com.atstudent.gmall.common.execption.GmallException;
import com.atstudent.gmall.common.feign.interceptor.AuthUserInfo;
import com.atstudent.gmall.common.feign.product.SkuFeignClient;
import com.atstudent.gmall.common.feign.util.AuthUserInfoUtils;
import com.atstudent.gmall.common.result.Result;
import com.atstudent.gmall.common.result.ResultCodeEnum;
import com.atstudent.gmall.product.entity.SkuInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

/**
 * @Author 薛有朋
 * @CreatDate 2025/4/8 20:34
 **/
@Service
@Slf4j
public class CartBizServiceImpl implements CartBizService {

    @Autowired
    private RedisTemplate<String , String> redisTemplate;

    @Autowired
    private SkuFeignClient skuFeignClient;

    @Override
    public AddCartSuccessVo addCart(Long skuId, Integer skuNum) {
        log.info("addCart...执行了");

        //构建Redis的数据key
        String  cartRedisKey = buildRedisKey() ;

        //把商品添加购物车中
        //判断当前要添加的商品在购物车是否存在，如果不存在直接创建一个购物项数据对象，然后把购物项添加到购物车中
        Boolean result = redisTemplate.opsForHash().hasKey(cartRedisKey, String.valueOf(skuId));//大key和小key

        //远程调用service-product微服务的查询商品详情接口
        SkuInfo skuInfo = skuFeignClient.findSkuInfoBySkuId(skuId).getData();

        if (result){ // 如果已经存在，购物项的数量进行加操作

            //先获取到Redis中的这个购物项
            //String.valueOf的作用是 将别的类型转换成String类型的字符串 这儿是把long类型的skuId转换成String类型的字符串
            String cartItemJson = redisTemplate.opsForHash().get(cartRedisKey, String.valueOf(skuId)).toString();
            //JSON.parseObject，是将Json字符串解析为相应的对象 也就是CartItem对象
            CartItem cartItem = JSON.parseObject(cartItemJson, CartItem.class);
            cartItem.setSkuNum(cartItem.getSkuNum() + skuNum);

            //控制购买数量
            Integer itemSkuNum = cartItem.getSkuNum();
            if (itemSkuNum > 10){
                cartItem.setSkuNum(10);
            }

            //将数据存入到Redis中 大key 小key  值
            redisTemplate.opsForHash().put(cartRedisKey , String.valueOf(skuId) , JSON.toJSONString(cartItem));

        }else { // 如果不存在直接创建一个购物项数据对象，然后把购物项添加到购物车中

            //对某个用户限制能添加的商品种类 限制为2种
            Long count = redisTemplate.opsForHash().size(cartRedisKey);
            if (count > 2){
                throw new GmallException(ResultCodeEnum.CART_ITEM_NUMBER_ERROR);
            }

            CartItem cartItem = new CartItem();
            cartItem.setId(skuId);
            cartItem.setSkuId(skuId);
            cartItem.setCartPrice(skuInfo.getPrice());
            cartItem.setSkuPrice(skuInfo.getPrice());
            //控制购买数量
            if (skuNum > 10){
                skuNum = 10;
            }
            cartItem.setSkuNum(skuNum);
            cartItem.setImgUrl(skuInfo.getSkuDefaultImg());
            cartItem.setSkuName(skuInfo.getSkuName());
            cartItem.setIsChecked(0);
            cartItem.setCreateTime(new Date());
            cartItem.setUpdateTime(new Date());

            //将数据存入到Redis中 大key 小key  值
            redisTemplate.opsForHash().put(cartRedisKey , String.valueOf(skuId) , JSON.toJSONString(cartItem));
        }

        // 构建响应结果 并返回值
        AddCartSuccessVo addCartSuccessVo = new AddCartSuccessVo() ;
        addCartSuccessVo.setSkuInfo(skuInfo);
        addCartSuccessVo.setSkuNum(skuNum);

        //针对临时购物车设置过期时间
        //先判断是否为临时购物车
        String userId = AuthUserInfoUtils.getAuthUserInfo().getUserId();
        if (StringUtils.isEmpty(userId)){ //userId为空，说明登录的是临时用户
            //获取临时购物车的过期时间 如果为-1 则未设置过期时间
            Long expire = redisTemplate.getExpire(cartRedisKey);
            if (expire == -1){ //设置过期时间
                redisTemplate.expire(cartRedisKey , 30 , TimeUnit.MINUTES);
            }
        }

        return addCartSuccessVo;
    }

    @Override
    public void deleteAllChecked() {
        //先拿到Redis数据key
        String  cartRedisKey = buildRedisKey() ;
        //拿到所有购物车数据 遍历看isChecked是否为1 为1的删除
        redisTemplate.opsForHash().values(cartRedisKey).stream().forEach(obj ->{
            String cartItemJSON = obj.toString();
            CartItem cartItem = JSON.parseObject(cartItemJSON, CartItem.class);
            Integer isChecked = cartItem.getIsChecked();
            if (isChecked == 1){
                redisTemplate.opsForHash().delete(cartRedisKey , String.valueOf(cartItem.getSkuId()));
            }
        });
    }

    private String buildRedisKey() {
        AuthUserInfo authUserInfo = AuthUserInfoUtils.getAuthUserInfo();
        if (authUserInfo != null){
            String userId = authUserInfo.getUserId();
            String userTempId = authUserInfo.getUserTempId();
            if (!StringUtils.isEmpty(userId)){ //userId不为空 则使用userId作为数据key 否则使用临时用户的userTempId
                return GmallConstant.REDIS_CART_PRE + userId ;
            }else {
                return GmallConstant.REDIS_CART_PRE + userTempId;
            }
        }else {
            return null;
        }
    }
}
